Now that we can display digits form our program we could create a counter. With the LEDs connected we only have one pin spare, but we can use this as an input and then count the number of times it is pressed. Note that for the counter to work reliably we must de-bounce the button.
I use the DIV
and MOD
operators
to calculate the thousands, tens and units digits in turn. A number % (MOD) 10
gives me the value of the units digit. Once I have got the units digits I divide the incoming number by 10 (which moves the tens digit down into the units position) and then repeat the process.
I now have a function which can display a decimal number, which might turn out to be useful. Programming purists will probably complain that making the PICmicro do all these divisions by 10 (which is rather hard work for such a simple processor) is a bit cruel if all I want is a counter, but it does work. On the right you can see the parts that I added to make my counter. All I needed was a way of printing numbers, a key debounce function and a count variable.
Run Exercise 4.5. You should notice that the number gets one bigger each time you press the button on LA4
.
Note that in the setup_hardware function, we need to set the pins on PORTA to be digital inputs, we do this be setting the contents of the 'ADCON' register to 0.
/* EX 4.5 LED counter */
/* modified version of get button*/
/* which only looks at pin 4 of */
/* PORTA */
unsigned char get_button ( void )
{
unsigned char i;
unsigned char oldv, newv ;
oldv = PORTA & 16 ;
i = 0 ;
while ( i < 20 )
{
newv = PORTA & 16 ;
if ( oldv == newv )
{
i++ ;
}
else
{
i = 0 ;
oldv = newv ;
}
}
/* we have a steady value */
return oldv ;
}
void display_value ( int value )
{
/* display the units */
display ( value % 10, 3 ) ;
value = value / 10 ;
/* display the tens */
display ( value % 10, 2 ) ;
value = value / 10 ;
/* display the hundreds */
display ( value % 10, 1 ) ;
value = value / 10 ;
/* display the thousands */
display ( value % 10, 0 ) ;
}
void main ( void )
{
/* our counter value */
int count = 0 ;
setup_hardware () ;
display_value ( count ) ;
while (1)
{
/* wait for a button down */
while ( get_button () == 0 ) ;
count = count + 1 ; ;
display_value ( count ) ;
/* wait for a button up */
while ( get_button () == 1 ) ;
}
}